package fr.afcepf.hotels.soa.dao;

// package com.formation.dao;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

public abstract class GenericDAO<T> {
 private final static String UNIT_NAME = "JPADB";

 @PersistenceContext(unitName = UNIT_NAME)
 protected EntityManager em;
 //private EntityManager em;
 
 private Class<T> entityClass;

 public GenericDAO(Class<T> entityClass) {
  this.entityClass = entityClass;
 }
 

 public void save(T entity) {
	  em.persist(entity);
	 }

	 public void delete(T entity) {
	  T toRemoved = em.merge(entity);

	  em.remove(toRemoved);
	 }

	 public T update(T entity) {
	  return em.merge(entity);
	 }

	 public T find(int entityID) {
	  return em.find(entityClass, entityID);
	 }

	 // car jpa ne possede pas de methode
	 // em.getCriteriaBuilder().createQuery()<T> method
	 @SuppressWarnings({ "rawtypes", "unchecked" })
	public List<T> findAll() {
	  CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
	  cq.select(cq.from(entityClass));
	  return em.createQuery(cq).getResultList();
	 }

	 // car jpa ne possede pas de methode
	 // ery.getSingleResult()<T> method
	 @SuppressWarnings("unchecked")
	protected T findOneResult(String namedQuery, Map<String, Object> parameters) {
	  T result = null;

	  try {
	   Query query = em.createNamedQuery(namedQuery);

	   // ssi parametres pas null et non vide
	   if (parameters != null && !parameters.isEmpty()) {
	    populateQueryParameters(query, parameters);
	   }

	   result = (T) query.getSingleResult();

	  } catch (Exception e) {
	   System.out.println("Error while running query: " + e.getMessage());
	   e.printStackTrace();
	  }

	  return result;
	 }

	 private void populateQueryParameters(Query query, Map<String, Object> parameters) {

	  for (Entry<String, Object> entry : parameters.entrySet()) {
	   query.setParameter(entry.getKey(), entry.getValue());
	  }
	 }
	}
